﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ProgramDioptase.CatalogItems;
using ProgramDioptase.Interfaces;
using ProgramDioptase.ItemTypes;

namespace ProgramDioptase
{
    public sealed class DataManager : IManageable
    {
        public static Uri ResourcePath = new Uri(@"Resources", UriKind.RelativeOrAbsolute);
        public static Uri ClientPath = new Uri(@"Clients", UriKind.RelativeOrAbsolute);
        public static Uri LibraryPath = new Uri(@"Library", UriKind.RelativeOrAbsolute);
        public static Uri MoviePath = new Uri(string.Format(@"../../{0}\Movies", LibraryPath), UriKind.RelativeOrAbsolute);
        public static Uri GamePath = new Uri(string.Format(@"../../{0}\Games", LibraryPath), UriKind.RelativeOrAbsolute);
        public static Uri MusicPath = new Uri(string.Format(@"../../{0}\Music", LibraryPath), UriKind.RelativeOrAbsolute);

        private static readonly DataManager instance = new DataManager();

        static DataManager()
        {
            Instance.Movies = Instance.GetItems<Movie>(MoviePath);
            Instance.Games = Instance.GetItems<Game>(GamePath);
            Instance.Music = Instance.GetItems<Music>(MusicPath);
        }

        private DataManager()
        {
        }

        public static DataManager Instance
        {
            get { return instance; }
        }

        public IList<Movie> Movies { get; set; }
                
        public IList<Game> Games { get; set; }

        public IList<Music> Music { get; set; }
                
        public IList<T> GetItems<T>(Uri baseDirectory) where T : CatalogItem, new()
        {
            var allItems = new List<T>();

            if (Directory.Exists(baseDirectory.ToString()) && File.Exists(string.Format(@"{0}\items.txt", baseDirectory)))
            {
                // Reading all items names
                var itemNames = Instance.ReadItemsNames(baseDirectory);
                
                // Reading item information by item name
                foreach (var itemName in itemNames)
                {
                    string itemDirectory = string.Format(@"{0}\{1}", baseDirectory, itemName);

                    if (Directory.Exists(itemDirectory) && File.Exists(itemDirectory + @"\info.txt"))
                    {
                        using (StreamReader itemInfo = new StreamReader(string.Format(@"{0}\{1}\info.txt", baseDirectory, itemName)))
                        {
                            string[] components = itemInfo.ReadToEnd().Split(';');

                            var currentItem = new T();
                            currentItem.Initialize(components);

                            allItems.Add(currentItem);
                        }
                    }
                }
            }

            return allItems;
        }
                
        public IList<string> ReadItemsNames(Uri baseDirectory)
        {
            var itemNames = new List<string>();

            using (StreamReader itemNameReader = new StreamReader(string.Format(@"{0}\items.txt", baseDirectory)))
            {
                while (!itemNameReader.EndOfStream)
                {
                    itemNames.Add(itemNameReader.ReadLine());
                }
            }

            return itemNames;
        }
    }
}